//standard
#include <istream>
#include <numeric>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <cstdlib>

// boost
#include <boost/format.hpp>

// components
#include <tree.h>
#include <matrix.h>
#include <matrix_io.h>
#include <print_error.h>
#include <stlhelper.h>
#define DEBUG_LEVEL 2
#include <debug_func.h>


#include <boost/tuple/tuple.hpp>

#include "get_arg.h"

using boost::format;
using std::vector;
using std::ostringstream;

using std::string;
using std::fill;
using std::ofstream;
using std::cout;
using std::cin;
using std::ifstream;
using boost::tie;
using std::pair;
using std::istream;
using std::max;
using std::min;
using namespace bcpp_matrix;

//________________________________________________________________________________________

//	read_tree_matrix_from_stream

//		reconstruct matrix from a tree in new hampshire format

//________________________________________________________________________________________
void read_tree_matrix_from_stream(istream& istrm, t_matrix_f& tree_matrix)
{
	bcpp_tree::t_tree tree;
	unsigned line_cnt = 0;
	istrm >> bcpp_tree::t_tree_io_wrapper(tree, line_cnt);
	tree.to_matrix(tree_matrix);
	tree_matrix.matrix_name = tree.get_name();
}




//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

//	main

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
int main (int argc, char *argv[])
{
	// we use cout to print progress so flush per call
	cout.setf(std::ios_base::unitbuf);

	std::ios::sync_with_stdio(false);

	t_program_args args;
	try
	{
	if (!process_command_line_options(argc, argv, args))
		return 1;


//    char buff[4096];
//    cin.rdbuf()->pubsetbuf(buff, 32768); // enable buffering


	//
	//	read tree matrix from cin
	//
	args.VERBOSE() << "\tReading tree...\n";
	t_matrix_f tree_matrix;
	read_tree_matrix_from_stream(cin, tree_matrix);

	tree_matrix.sort_by_name_alpha();

	if (!args.header)
		tree_matrix.matrix_name= "";

	args.VERBOSE() << "\tWriting matrix";
	if (args.header)
		args.VERBOSE() << " with header";
	args.VERBOSE() << "...\n";
	
	std::ostringstream ignore;
	t_progress_indicator dots(ignore,  10000000);
	cout << t_matrix_ostrm_wrapper_f(tree_matrix, args.output_format, dots);
	//write_matrix(cout, tree_matrix, args.output_format, false);

	}
	catch(std::exception& e)
	{
		std_print_error(args.CERR(), e.what());
		return 1;
	}
	return 0;
}



